package com.hippo.javacore.multithreading;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName ThreadDemo
 * @Description TODO 线程池--自定义线程池
 * @Author tangxl
 * @create 2023-03-16 15:47
 **/
public class ThreadDemo16 {
    public static void main(String[] args) {

        /**
         *  ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor
         *  (corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
         *  (1) corePoolSize：核心线程数，线程池中的常驻核心线程数，即使没有任务需要执行，也不会回收。
         *  (2) maximumPoolSize：线程池能够容纳同时执行的最大线程数，此值必须大于等于1。
         *  (3) keepAliveTime：多余的空闲线程的存活时间，当线程池中的线程数量超过corePoolSize时，如果某线程空闲时间达到keepAliveTime，
         *  则会终止，直到线程数量等于corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法，在线程池中的线程数量不超过corePoolSize时，
         *  该参数也会生效，直到线程数量为0。
         *  (4) unit：keepAliveTime的单位，有7种取值，在TimeUnit类中有7种静态属性：
         *  TimeUnit.DAYS;               //天
         *  TimeUnit.HOURS;             //小时
         *  TimeUnit.MINUTES;           //分钟
         *  TimeUnit.SECONDS;           //秒
         *  TimeUnit.MILLISECONDS;      //毫秒
         *  TimeUnit.MICROSECONDS;      //微妙
         *  TimeUnit.NANOSECONDS;       //纳秒
         *  (5) workQueue：任务队列，被提交但尚未被执行的任务。
         *  (6) threadFactory：表示生成线程池中工作线程的线程工厂，用于创建线程，一般用默认的即可。
         *  (7) handler：拒绝策略，表示当队列满了并且工作线程大于等于线程池的最大线程数（maximumPoolSize）时如何来拒绝请求执行的runnable的策略。
         *  一般有以下4种策略：
         *  ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
         *  ThreadPoolExecutor.DiscardPolicy：也是丢弃任务，但是不抛出异常。
         *  ThreadPoolExecutor.DiscardOldestPolicy：丢弃队列最前面的任务，然后重新尝试执行任务（重复此过程）
         *  ThreadPoolExecutor.CallerRunsPolicy：由调用线程处理该任务
         *
         *   allowCoreThreadTimeOut(boolean)：允许核心线程超时，默认为false，即核心线程不会超时。
         *   prestartAllCoreThreads()：预启动所有核心线程。
         *   prestartCoreThread()：预启动一个核心线程。
         *   remove(Runnable)：从线程池中移除某个任务。
         *   purge()：移除线程池中所有的任务。
         *   shutdown()：关闭线程池，但是会等待线程池中的任务执行完毕。
         *   shutdownNow()：关闭线程池，并且尝试停止正在执行的任务。
         *   execute(Runnable)：执行任务。
         *   getActiveCount()：获取线程池中活跃的线程数。
         *   getCompletedTaskCount()：获取已完成的任务数量。
         *   getCorePoolSize()：获取核心线程数。
         *   getKeepAliveTime(TimeUnit)：获取线程池中线程的空闲时间。
         *   getLargestPoolSize()：获取线程池中曾经创建过的最大线程数。
         *   getMaximumPoolSize()：获取线程池中允许的最大线程数。
         *   getPoolSize()：获取线程池中当前的线程数。
         *   getQueue()：获取线程池中的任务队列。
         *   getTaskCount()：获取线程池中的任务总数。
         *   isShutdown()：判断线程池是否已经关闭。
         *   isTerminated()：判断线程池是否已经终止。
         *   isTerminating()：判断线程池是否正在终止。
         *   awaitTermination(long, TimeUnit)：等待线程池终止。
         *   toString()：返回线程池的字符串表示。
         *   getThreadFactory()：获取线程工厂。
         *   setThreadFactory(ThreadFactory)：设置线程工厂。
         *   getRejectedExecutionHandler()：获取拒绝策略。
         *   getQueue()：获取任务队列。
         *   setCorePoolSize(int)：设置核心线程数。
         *   setMaximumPoolSize(int)：设置线程池中允许的最大线程数。
         *   setKeepAliveTime(long, TimeUnit)：设置线程池中线程的空闲时间。
         *   setRejectedExecutionHandler(RejectedExecutionHandler)：设置拒绝策略。
         *   setThreadFactory(ThreadFactory)：设置线程工厂。
         *   setQueueCapacity(int)：设置任务队列的容量。
         *   setAllowCoreThreadTimeOut(boolean)：设置是否允许核心线程超时。
         *   setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean)：设置是否允许定时任务在关闭线程池后继续执行。
         *   setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean)：设置是否允许延时任务在关闭线程池后继续执行。
         *   setRemoveOnCancelPolicy(boolean)：设置是否允许取消任务在关闭线程池后继续执行。
         *   setThreadNamePrefix(String)：设置线程名称的前缀。
         *   setWaitForTasksToCompleteOnShutdown(boolean)：设置是否允许关闭线程池后等待任务执行完毕。
         *   setAwaitTerminationSeconds(int)：设置关闭线程池后等待任务执行完毕的时间。
         *   setKeepAliveSeconds(int)：设置线程池中线程的空闲时间。
         */

        // 自定义线程池
        ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        // 执行任务
        pool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
        });

        // 关闭线程池
        pool.shutdown();
    }

}
